package cn.forward.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.forward.constants.GlobalExceptionCode;
import cn.forward.exception.GlobalException;
import cn.forward.mapper.LoginMapper;
import cn.forward.mapper.PermissionMapper;
import cn.forward.param.AppLoginParam;
import cn.forward.pojo.domain.Login;
import cn.forward.pojo.dto.Admin;
import cn.forward.pojo.dto.LoginInfoDto;
import cn.forward.pojo.vo.LoginVo;
import cn.forward.properties.RedisKeyProperties;
import cn.forward.service.ILoginService;
import cn.forward.template.WechatTemplate;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.crypto.digest.BCrypt;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 登录表 服务实现类
 * </p>
 *
 * @author forward
 * @since 2025-03-24
 */
@Service
@Slf4j
public class LoginServiceImpl extends ServiceImpl<LoginMapper, Login> implements ILoginService {


    @Autowired
    private WechatTemplate wechatTemplate;

    @Autowired
    private PermissionMapper permissionMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    RedisKeyProperties redisKeyProperties;


    /**
     * 注册到login登录表
     * @param appLoginParam
     */


    @Override
    public void appSave(AppLoginParam appLoginParam) {


        Login login = new Login();
        BeanUtil.copyProperties(appLoginParam,login);
        login.setDeleted(false);
        login.setCreateTime(new Date());
        login.setVersion(0);


        super.save(login);
    }


    /**
     * 小程序端司机乘客登录实现
     * @param openIdCode
     * @param type
     * @return
     */

    @Override
    public LoginVo wxLogin(String openIdCode, String type) {
        String openId = wechatTemplate.openIdByCode(openIdCode);

        Login login = super.getOne(new LambdaQueryWrapper<Login>().eq(Login::getOpenId, openId).eq(Login::getType, type));

        if (ObjectUtil.isNull(login)){
            throw  new GlobalException(GlobalExceptionCode.NO_PERMISSION);
        }
        Long loginId = login.getId();
        StpUtil.login(loginId);

        List<String> permissions = permissionMapper.loginPermission(loginId);


        String KenName = String.format(redisKeyProperties.getRedisKey(), loginId);

        long tokenTimeout = StpUtil.getTokenTimeout();

        redisTemplate.opsForValue().set(KenName,permissions,tokenTimeout, TimeUnit.SECONDS);


        LoginInfoDto loginInfoDto = BeanUtil.copyProperties(login, LoginInfoDto.class);

        String tokenName = StpUtil.getTokenName();
        String tokenValue = StpUtil.getTokenValue();

        return new LoginVo(tokenName,tokenValue,permissions,loginInfoDto);


    }

    /**
     * 管理端登录实现
     * @param admin
     * @return
     */

    @Override
    public LoginVo adminLogin(Admin admin) {

        Login adminLogin = super.getOne(new LambdaQueryWrapper<Login>().eq(Login::getType, admin.getType())
                .eq(Login::getUsername, admin.getUserName()));
        if (ObjectUtil.isNull(adminLogin)){
            throw new GlobalException(GlobalExceptionCode.PARAM_CODE_ERROR);
        }
        String password = adminLogin.getPassword();
        boolean checkpw = BCrypt.checkpw(password, admin.getPassword());
        if (! checkpw){
            throw new GlobalException(GlobalExceptionCode.WECHAT_PASSWORD_ERROR);
        }

        String tokenName = StpUtil.getTokenName();
        String tokenValue = StpUtil.getTokenValue();
        long loginIdAsLong = StpUtil.getLoginIdAsLong();
        String redisKey = redisKeyProperties.getRedisKey();
        String formatKey = String.format(redisKey, loginIdAsLong);
        long tokenTimeout = StpUtil.getTokenTimeout();
        List<String> loginPermission = permissionMapper.loginPermission(loginIdAsLong);

        redisTemplate.opsForValue().set(formatKey,loginPermission,tokenTimeout,TimeUnit.SECONDS);

        LoginInfoDto loginInfoDto = BeanUtil.copyProperties(adminLogin, LoginInfoDto.class);

        return new LoginVo(tokenName,tokenValue,loginPermission,loginInfoDto);



    }


}
